﻿Imports System.Threading
Imports System.Windows.Threading
Imports System.Windows.Media.Animation
Imports System.IO
Imports System.Windows.Controls.Primitives
Imports FixSoft.Tools.FileAssociationTools
Imports FixSoft.Tools.TaskDialogTools
Imports FixSoft.Tools.ETaskDialog

Class MainWindow
    Dim WithEvents FileTools As New FileSplitter
    Dim SThread As New Thread(AddressOf Split)
    Private Sub Split(ByVal SplitArgument As SplitArgument)
        Try
            FileTools.Split(SplitArgument.Sourse, SplitArgument.Output, SplitArgument.SplitSize)
            Me.Dispatcher.Invoke(DispatcherPriority.Normal, DirectCast(AddressOf SplitFinish, Action))
            MessageBox.Show("The file has been splited.", "Complete Spliting", MessageBoxButton.OK, MessageBoxImage.Information)
        Catch ex As ArgumentException
            Me.Dispatcher.Invoke(DispatcherPriority.Normal, DirectCast(AddressOf SplitFinish, Action))
            MessageBox.Show(ex.Message, Forms.Application.ProductName, MessageBoxButton.OK, MessageBoxImage.Error)
        End Try
    End Sub
    Dim MThread As New Thread(AddressOf Merge)
    Private Sub Merge(ByVal MergeArgument As MergeArgument)
        If MergeArgument.IsAllParts Then
            If MergeArgument.IsOutput = False Then
                FileTools.Join(MergeArgument.Sourses)
            Else
                FileTools.Join(MergeArgument.Output, MergeArgument.Sourses)
            End If
        Else
            If MergeArgument.IsOutput = False Then
                FileTools.Join(MergeArgument.Sourse)
            Else
                FileTools.Join(MergeArgument.Sourse, MergeArgument.Output)
            End If
        End If
        Me.Dispatcher.Invoke(DispatcherPriority.Normal, DirectCast(AddressOf MergeFinish, Action))
        MessageBox.Show("The parts have been merged.", "Complete Merging", MessageBoxButton.OK, MessageBoxImage.Information)
    End Sub
    Sub ChangeByAnimation(ByVal Control As Control, ByRef [Property] As DependencyProperty, ByVal [From] As Double, ByVal [To] As Double, ByVal Duration As Double, Optional ByVal AutoReserve As Boolean = False)
        'Register the window's name, this is necessary for creating Storyboard using codes instead of XAML
        NameScope.SetNameScope(Control, New NameScope())
        Control.RegisterName(Control.Name, Control)
        'Create the fade in & fade out animation
        Dim winFadeAni As New DoubleAnimation()
        winFadeAni.From = [From]
        winFadeAni.[To] = [To]
        winFadeAni.Duration = New Duration(TimeSpan.FromSeconds(Duration))
        winFadeAni.AutoReverse = AutoReserve
        ' Configure the animation to target the window's opacity property
        Storyboard.SetTargetName(winFadeAni, Control.Name)
        Storyboard.SetTargetProperty(winFadeAni, New PropertyPath([Property]))
        ' Add the fade in & fade out animation to the Storyboard
        Dim winFadeStoryBoard As New Storyboard()
        winFadeStoryBoard.Children.Add(winFadeAni)
        winFadeStoryBoard.Begin(Control)
    End Sub
    ''' <summary>
    ''' Displays a message in a TaskDialog, waits for the user to click a button, and then returns an integer indicating which button the user clicked.
    ''' </summary>
    ''' <param name="Prompt">Required. String expression displayed as the message in the dialog box. The maximum length of Prompt is approximately 1024 characters, depending on the width of the characters used. If Prompt consists of more than one line, you can separate the lines using a carriage return character (Chr(13)), a line feed character (Chr(10)), or a carriage return/linefeed character combination (Chr(13) &amp; Chr(10)) between each line.</param>
    ''' <param name="Buttons">Optional. Numeric expression that is the sum of values specifying the number and type of buttons to display, the icon style to use, the identity of the default button, and the modality of the message box. If you omit Buttons, the default value is zero.</param>
    ''' <param name="Title"> String expression displayed in the title bar of the dialog box. If you omit Title, the application name is placed in the title bar.</param>
    ''' <returns>ConstantValueOK1Cancel2Abort3Retry4Ignore5Yes6No7</returns>
    Private Function MsgBoxa(ByVal Prompt As String, Optional ByVal Buttons As MsgBoxStyle = MsgBoxStyle.OkOnly, Optional ByVal Title As Object = Nothing) As MsgBoxResult
        If Title Is Nothing Then
            Title = Forms.Application.ProductName
        End If
        If Buttons And MsgBoxStyle.Critical Then
            MessageBox.Show("C")
        End If
    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Select Case sender.Content
            Case "Split"
                If File.Exists(TSrcS.Text) = False Then
                    MsgBox("The sourse file doesn't exist.", MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)
                    Exit Sub
                ElseIf GetSplitSize() = 0 Then
                    MsgBox("The size of each part or number of parts is zero.", MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)
                    Exit Sub
                End If
                Dim tmp As New SplitArgument With {.Sourse = TSrcS.Text, .Output = If(CIsout.IsChecked, ToutS.Text, TSrcS.Text), .SplitSize = GetSplitSize()}
                SThread.Start(tmp)
                Button1.Content = "Pause"
                BtnCancel.IsEnabled = True
                Exit Select
            Case "Pause"
                SThread.Suspend()
                Button1.Content = "Resume"
                Exit Select
            Case "Resume"
                SThread.Resume()
                Button1.Content = "Pause"
                Exit Select
        End Select
    End Sub
    Private Function GetSplitSize()
        Try
            Dim SplitSize As Integer
            If RSSOB.IsChecked Then
                SplitSize = Val(Ssize.Text) * ToByte()
            Else
                Dim Value As Integer = Val(SNOP.Text)
                If Value = 0 Then
                    Return 0
                End If
                SplitSize = FileSplitter.FileSize(TSrcS.Text) / Value
            End If
            Return SplitSize
        Catch ex As OverflowException
            MsgBox(ex.Message + vbNewLine + "Use smaller values.", MsgBoxStyle.OkOnly + vbCritical)
            If RSSOB.IsChecked Then
                Ssize.Text = "0"
            Else
                SNOP.Text = "0"
            End If
            Return 0
        End Try
    End Function
    Private Function ToByte()
        If RSSOB.IsChecked Then
            Select Case Stb.SelectedItem.Content
                Case "Byte"
                    Return 1
                Case "KB"
                    Return 1024
                Case "MB"
                    Return 1024 * 1024
                Case "GB"
                    Return 1024 * 1024 * 1024
                Case Else
                    Return 1
            End Select
        Else
            Return 1024 * 1024
        End If
    End Function
    Private Function ToUnit()
        If RSSOB.IsChecked Then
            Return Stb.SelectedItem.Content
        Else
            Return "MB"
        End If
    End Function
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click
        Dim o As New Forms.OpenFileDialog
        o.Filter = "All Files (*.*)|*.*"
        If o.ShowDialog() <> Forms.DialogResult.Cancel Then
            TSrcS.Text = o.FileName
        End If
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button3.Click
        Dim s As New Forms.SaveFileDialog
        s.OverwritePrompt = False
        If File.Exists(TSrcS.Text) Then
            Dim fi As New FileInfo(TSrcS.Text)
            s.Filter = fi.Extension.Substring(1).ToUpper + " Files(*." + fi.Extension.Substring(1) + ")|" + "*" + fi.Extension + "|All Files (*.*)|*.*"
        Else
            s.Filter = "All Files (*.*)|*.*"
        End If
        If s.ShowDialog <> Forms.DialogResult.Cancel Then
            ToutS.Text = s.FileName
        End If
    End Sub

    Private Sub FileTools_JoinProgressUpdated(ByVal sender As Object, ByVal e As ProgressEventArgs) Handles FileTools.JoinProgressUpdated
        Me.Dispatcher.Invoke(DispatcherPriority.Normal, DirectCast(Sub()
                                                                       Try
                                                                           MCProgressBar.Value = e.CurrentProgress
                                                                           MOProgressBar.Value = e.OverallProgress
                                                                       Catch ex As Exception

                                                                       End Try
                                                                   End Sub, Action))
    End Sub

    Private Sub FileTools_ProgressUpdated(ByVal sender As Object, ByVal e As ProgressEventArgs) Handles FileTools.SplitProgressUpdated
        Me.Dispatcher.Invoke(DispatcherPriority.Normal, DirectCast(Sub()
                                                                       Try
                                                                           SCProgressBar.Value = e.CurrentProgress
                                                                           SOProgressBar.Value = e.OverallProgress
                                                                       Catch ex As Exception

                                                                       End Try
                                                                   End Sub, Action))
    End Sub

    Private Sub MainWindow_AeroEffectDisabled(ByVal sender As Object, ByVal e As Fixed.Windows.AeroEffectChangedEvenArgs) Handles Me.AeroEffectDisabled
        Me.Background = TmpBackground
        Dim myStoryboard As Storyboard = DirectCast(FindResource("The turn"), Storyboard)
        myStoryboard.Begin()
    End Sub

    Private Sub MainWindow_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        Application.Current.Shutdown()
    End Sub
    Dim TmpBackground As Brush
    Public Overrides Sub ResetAreoBackground()
        If TmpBackground Is Nothing Then
            TmpBackground = Background
        End If
        MyBase.ResetAreoBackground()
    End Sub
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Msf.ItemsSource = sourses
        SThread.Priority = ThreadPriority.Highest
        MThread.Priority = ThreadPriority.Highest
        LVer.Text = "Version " + Forms.Application.ProductVersion
        LName.Text = Forms.Application.ProductName
        If AeroEnabled = False Then
            Dim myStoryboard As Storyboard = DirectCast(FindResource("The turn"), Storyboard)
            myStoryboard.Begin()
        End If
        Try
            FileAssociation.AssociationFile("001", "FileSplitter/SplitedFile", "First part of a file that it have been splited", "001 file", , "SplitedFile", "Merge")
        Catch

        End Try
        Dim Cmm As String = Command()
        If File.Exists(Cmm) Then
            tabControl.SelectedIndex = 1
            TMsrc.Text = Cmm
            BtnMerge_Click(BtnMerge, New RoutedEventArgs)
        ElseIf Cmm.StartsWith("Split") Then
            Dim Args As String() = Cmm.Split("|")
            tabControl.SelectedIndex = 0
            TSrcS.Text = Args(1)
            If Args.Length = 3 Then
                CIsout.IsChecked = True
                ToutS.Text = Args(2)
            End If
            Button1_Click(Button1, New RoutedEventArgs)
        ElseIf Cmm.StartsWith("Merge") Then
            Dim Args As String() = Cmm.Split("|")
            tabControl.SelectedIndex = 1
            For i = 1 To Args.GetUpperBound(0)
                sourses.Add(New Sourse With {.FilePath = Args(i)})
            Next
            Rmap.IsChecked = True
            UpdateMsf()
            BtnMerge_Click(BtnMerge, New RoutedEventArgs)
        End If
    End Sub

    Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles SH.Click, SAN.Click, SN.Click, SBN.Click, SL.Click
        If sender.IsChecked = False Then
            sender.IsChecked = True
        End If
        For Each Item As MenuItem In SMOptions.Items
            If Item IsNot sender Then
                Item.IsChecked = False
            End If
        Next
        UpdateSplitingPriority()
    End Sub
    Private Sub MergePC_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MH.Click, MAN.Click, MN.Click, MBN.Click, ML.Click
        If sender.IsChecked = False Then
            sender.IsChecked = True
        End If
        For Each Item As MenuItem In MPOptions.Items
            If Item IsNot sender Then
                Item.IsChecked = False
            End If
        Next
        UpdateMergingPriority()
    End Sub
    Private Sub UpdateSplitingPriority()
        If SH.IsChecked Then
            SThread.Priority = ThreadPriority.Highest
        ElseIf SAN.IsChecked Then
            SThread.Priority = ThreadPriority.AboveNormal
        ElseIf SN.IsChecked Then
            SThread.Priority = ThreadPriority.Normal
        ElseIf SBN.IsChecked Then
            SThread.Priority = ThreadPriority.BelowNormal
        ElseIf SL.IsChecked Then
            SThread.Priority = ThreadPriority.Lowest
        End If
    End Sub
    Private Sub UpdateMergingPriority()
        If MH.IsChecked Then
            MThread.Priority = ThreadPriority.Highest
        ElseIf MAN.IsChecked Then
            MThread.Priority = ThreadPriority.AboveNormal
        ElseIf MN.IsChecked Then
            MThread.Priority = ThreadPriority.Normal
        ElseIf MBN.IsChecked Then
            MThread.Priority = ThreadPriority.BelowNormal
        ElseIf ML.IsChecked Then
            MThread.Priority = ThreadPriority.Lowest
        End If
    End Sub
    Private Sub RSSOB_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles RSSOB.Checked
        If SNOP Is Nothing Then
            Exit Sub
        End If
        SNOP.IsEnabled = False
        Ssize.IsEnabled = True
        Stb.IsEnabled = True
        UpdateStatus()
    End Sub

    Private Sub RSNOB_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles RSNOB.Checked
        Ssize.IsEnabled = False
        Stb.IsEnabled = False
        SNOP.IsEnabled = True
        UpdateStatus()
    End Sub
    Private Sub ChangeProgressValue(ByVal ProgressBar As ProgressBar, ByVal ToValue As Integer, Optional ByVal Duration As Double = 0.3)
        ChangeByAnimation(ProgressBar, Primitives.RangeBase.ValueProperty, ProgressBar.Value, ToValue, Duration)
    End Sub
    Private Sub UpdateStatus()
        If NsizePart Is Nothing Then
            Exit Sub
        End If
        If File.Exists(TSrcS.Text) = False Then
            NsizeSrc.Content = ""
            NsizePart.Content = ""
            NnumParts.Content = ""
            Exit Sub
        ElseIf GetSplitSize() = 0 Then
            NsizeSrc.Content = Str(FormatNumber(FileSplitter.FileSize(TSrcS.Text) / ToByte(), 3)) + " " + ToUnit()
            NsizePart.Content = "0"
            NnumParts.Content = "0"
            Exit Sub
        End If
        NsizeSrc.Content = Str(FormatNumber(FileSplitter.FileSize(TSrcS.Text) / ToByte(), 3)) + " " + ToUnit()
        NsizePart.Content = Str(FormatNumber(GetSplitSize() / ToByte(), 3)) + " " + ToUnit()
        Dim NumParts As Integer = Int(FileSplitter.FileSize(TSrcS.Text) / GetSplitSize())
        NnumParts.Content = If((FileSplitter.FileSize(TSrcS.Text) / GetSplitSize()) > NumParts, NumParts + 1, NumParts)
    End Sub

    Private Sub Stb_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles Stb.SelectionChanged
        UpdateStatus()
    End Sub

    Private Sub ToutS_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles TSrcS.TextChanged
        UpdateStatus()
    End Sub

    Private Sub SNOP_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles SNOP.LostFocus, Ssize.LostFocus
        UpdateStatus()
    End Sub

    Private Sub SNOP_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles SNOP.MouseMove, Ssize.MouseMove
        UpdateStatus()
    End Sub

    Private Sub SCProgressBar_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles SCProgressBar.ValueChanged
        CCPD.Text = Str(Int(sender.Value)) + "%"
    End Sub
    Private Sub SplitFinish()
        Button1.Content = "Split"
        BtnCancel.IsEnabled = False
        ChangeProgressValue(SCProgressBar, 0, 0.5)
        ChangeProgressValue(SOProgressBar, 0, 0.5)
        SThread = New Thread(AddressOf Split)
    End Sub
    Private Sub MergeFinish()
        BtnMerge.Content = "Merge"
        BtnCancelM.IsEnabled = False
        ChangeProgressValue(MCProgressBar, 0, 0.5)
        ChangeProgressValue(MOProgressBar, 0, 0.5)
        MThread = New Thread(AddressOf Merge)
    End Sub
    Private Sub BtnCancel_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnCancel.Click
        SThread.Abort()
        SplitFinish()
    End Sub

    Private Sub BtnMerge_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnMerge.Click
        Select Case sender.Content
            Case "Merge"
                If Rmap.IsChecked = False AndAlso File.Exists(TMsrc.Text) = False Then
                    MsgBox("The first part doesn't exist.", MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "Error: First part doesn't exist")
                    Exit Sub
                End If
                Dim tmp As New MergeArgument With {.Sourse = TMsrc.Text, .Output = ToutM.Text}
                tmp.IsOutput = CBisout.IsChecked
                tmp.IsAllParts = Rmap.IsChecked
                Dim AP As New List(Of String)
                For Each Item In sourses
                    AP.Add(Item.FilePath)
                Next
                tmp.Sourses = AP.ToArray
                MThread.Start(tmp)
                BtnMerge.Content = "Pause"
                BtnCancelM.IsEnabled = True
                Exit Select
            Case "Pause"
                MThread.Suspend()
                BtnMerge.Content = "Resume"
                Exit Select
            Case "Resume"
                MThread.Resume()
                BtnMerge.Content = "Pause"
                Exit Select
        End Select
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button4.Click
        Dim o As New Forms.OpenFileDialog
        o.Filter = "All Files (*.*)|*.*"
        If o.ShowDialog() <> Forms.DialogResult.Cancel Then
            TMsrc.Text = o.FileName
        End If
    End Sub

    Private Sub SOProgressBar_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles SOProgressBar.ValueChanged
        COVD.Text = Str(Int(sender.Value)) + "%"
    End Sub

    Private Sub MCProgressBar_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles MCProgressBar.ValueChanged
        MCCPD.Text = Str(Int(sender.Value)) + "%"
    End Sub

    Private Sub MOProgressBar_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles MOProgressBar.ValueChanged
        MCOVD.Text = Str(Int(sender.Value)) + "%"
    End Sub

    Private Sub CBisout_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles CBisout.Checked, CBisout.Unchecked
        ToutM.IsEnabled = CBisout.IsChecked
        BtnMoutB.IsEnabled = CBisout.IsChecked
    End Sub

    Private Sub BtnMoutB_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnMoutB.Click
        Dim s As New Forms.SaveFileDialog
        s.Filter = "All Files (*.*)|*.*"
        If File.Exists(TMsrc.Text) Then
            Dim fe As String = FileSplitter.GetPathWithoutExtension(TMsrc.Text)
            If Not (fe.LastIndexOfAny(".") < 0) Then
                fe = fe.Substring(fe.LastIndexOfAny("."))
                s.Filter = fe.Substring(1).ToUpper + " Files(*." + fe.Substring(1) + ")|" + "*" + fe + "|All Files (*.*)|*.*"
            End If
        ElseIf Rmap.IsChecked Then
            Dim fe As String = FileSplitter.GetPathWithoutExtension(sourses(0).FilePath)
            If Not (fe.LastIndexOfAny(".") < 0) Then
                fe = fe.Substring(fe.LastIndexOfAny("."))
                s.Filter = fe.Substring(1).ToUpper + " Files(*." + fe.Substring(1) + ")|" + "*" + fe + "|All Files (*.*)|*.*"
            End If
        End If
        If s.ShowDialog <> Forms.DialogResult.Cancel Then
            ToutM.Text = s.FileName
        End If
    End Sub

    Private Sub BtnCancelM_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnCancelM.Click
        MThread.Abort()
        MergeFinish()
    End Sub

    Private Sub Window_MouseLeftButtonDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles MyBase.MouseLeftButtonDown
        If e.Source Is Me OrElse TypeOf e.Source Is TextBlock OrElse TypeOf e.Source Is Rectangle OrElse TypeOf e.Source Is StatusBar OrElse TypeOf e.Source Is StatusBarItem OrElse TypeOf e.Source Is Image Then
            Me.DragMove()
        End If
    End Sub
    Dim sourses As New List(Of Sourse)
    Private Sub BtnBrwAP_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnBrwAP.Click
        Dim o As New Forms.OpenFileDialog
        o.Multiselect = True
        o.Filter = "All Files (*.*)|*.*"
        If o.ShowDialog() <> Forms.DialogResult.Cancel Then
            Dim fls = From File In CType(o.FileNames, Array) Order By File.Substring(File.LastIndexOfAny(".")) Select File
            For Each File In fls
                sourses.Add(New Sourse With {.FilePath = File})
            Next
            UpdateMsf()
        End If
    End Sub
    Private Sub UpdateMsf()
        Msf.ItemsSource = Nothing
        Msf.ItemsSource = sourses
    End Sub
    Private Sub Rmap_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Rmap.Checked, Rmap.Unchecked, Rmfp.Checked, Rmfp.Unchecked
        If TMsrc Is Nothing Then
            Exit Sub
        End If
        TMsrc.IsEnabled = Rmfp.IsChecked
        Button4.IsEnabled = Rmfp.IsChecked
        Msf.IsEnabled = Rmap.IsChecked
        BtnBrwAP.IsEnabled = Rmap.IsChecked
        BtnRs.IsEnabled = Rmap.IsChecked
        BtnUp.IsEnabled = Rmap.IsChecked
        BtnDown.IsEnabled = Rmap.IsChecked
    End Sub

    Private Sub BtnRs_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnRs.Click
        For Each Item In Msf.SelectedItems
            sourses.RemoveAt(Msf.Items.IndexOf(Item))
        Next
        UpdateMsf()
    End Sub

    Private Sub BtnUp_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnUp.Click
        Dim tmpIndex As Integer = Msf.SelectedIndex
        Dim tmpSelection(Msf.SelectedItems.Count - 1) As Sourse
        Msf.SelectedItems.CopyTo(tmpSelection, 0)
        For Each Item In tmpSelection
            Dim CurrentIndex As Integer = Msf.Items.IndexOf(Item)
            If CurrentIndex = 0 Then
                Continue For
            End If
            Dim tmp As Sourse = Msf.Items(CurrentIndex)
            sourses.RemoveAt(CurrentIndex)
            sourses.Insert(CurrentIndex - 1, tmp)
        Next
        UpdateMsf()
        Msf.SelectedIndex = tmpIndex - 1
    End Sub

    Private Sub BtnDown_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnDown.Click
        Dim tmpIndex As Integer = Msf.SelectedIndex
        Dim tmpSelection(Msf.SelectedItems.Count - 1) As Sourse
        Msf.SelectedItems.CopyTo(tmpSelection, 0)
        For Each Item In tmpSelection
            Dim CurrentIndex As Integer = Msf.Items.IndexOf(Item)
            If CurrentIndex = sourses.Count - 1 Then
                Continue For
            End If
            Dim tmp As Sourse = Msf.Items(CurrentIndex)
            sourses.RemoveAt(CurrentIndex)
            sourses.Insert(CurrentIndex + 1, tmp)
        Next
        UpdateMsf()
        Msf.SelectedIndex = tmpIndex + 1
    End Sub

    Private Sub Msf_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) Handles Msf.Drop
        Dim d As String() = e.Data.GetFormats
        Dim DropedFiles = e.Data.GetData(DataFormats.FileDrop)
        If DropedFiles Is Nothing Then
            Exit Sub
        End If
        DropedFiles = From File In CType(DropedFiles, Array) Order By File.Substring(File.LastIndexOfAny(".")) Select File
        For Each File In DropedFiles
            sourses.Add(New Sourse With {.FilePath = File})
        Next
        UpdateMsf()
    End Sub

    Private Sub Msf_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles Msf.KeyDown
        If e.Key = Key.Delete Then
            BtnRs_Click(BtnRs, New RoutedEventArgs)
        End If
    End Sub

    Private Sub CIsout_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles CIsout.Checked, CIsout.Unchecked
        Button3.IsEnabled = CIsout.IsChecked
        ToutS.IsEnabled = CIsout.IsChecked
    End Sub
End Class
Friend Class SplitArgument
    Public Property Sourse As String
    Public Property Output As String
    Public Property SplitSize As Integer
End Class
Friend Class MergeArgument
    Public Property Sourse As String
    Public Property Sourses As String()
    Public Property Output As String
    Public Property IsOutput As Boolean
    Public Property IsAllParts As Boolean
End Class